<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>漳州古城</title>

		<style>
			html{
				zoom: 0.68;  /*整体缩放*/
			}
			body {
			  margin-left: 130px;  /*设置一个适当的偏移量 */
			}
			#map{
			      position: relative;
			      background-size: cover; 
			}
			.circle {
			  fill: red;
			  z-index: 6;
			} 
			.location{
				position: absolute;
				cursor: pointer;  
			}
			#path{
				stroke: rgb(0, 0, 0, 0);  
				stroke-width: 2;
				fill: none;
			}
			#svgMap {
				position: absolute;
				left: 225px;
				top: 260px;
			    z-index: 0;  
			}
			.buttonW {
				position: relative;
				left:1303px;
				bottom:1040px;
				width: 110px;
				height: 60px;
				border-radius: 10%;
				background-color: #efb86e;
				font-size: 3ch;
				color: #4e2d02;
			    
			}
			.buttonB {
				position: relative;
				left:1329px;
				bottom:1040px;
				width: 110px;
				height: 60px;
				border-radius: 10%;
				background-color: #efb86e;
				font-size: 3ch;
				color: #4e2d02;
			    
			}
			.buttonC {
				position: relative;
				left:1355px;
				bottom:1040px;
				width: 110px;
				height: 60px;
				border-radius: 10%;
				background-color: #efb86e;
				font-size: 3ch;
				color: #4e2d02;
			    
			}
			.buttonR {
				position: relative;
				left:1250px;
				bottom:890px;
				width: 100px;
				height: 50px;
				border-radius: 10%;
				background-color: #efb86e;
				font-size: 2.2ch;
				color: #4e2d02;

			}
			.dist{
				position: relative;
				font-size: 3ch;
				left:1315px;
				bottom:745px;
			}
			.tim{
				position: relative;
				font-size: 3ch;
				left:1315px;
				bottom:880px;
			}
			
			.transformClick{
				transition: transform 0.3s ease-in-out, box-shadow 0.2s ease-in-out;
			}
			.transformClick:hover{
				transform: scale(1.05);
			}
			.hoverImg {
				display: none;
				position: absolute;
				height: 120px;
				z-index: 2;
				top: -130px; /* 根据实际图片大小调整 */
				left: 50%;  /* 让图片居中显示 */
				transform: translateX(-50%); /* 水平居中 */
				pointer-events: none; /* 防止图片挡住鼠标事件 */
			}
			.location:hover .hoverImg{
			    display: block;
			}
			.clicked{
				box-shadow: 0 0 10px 5px rgba(250, 135, 100, 0.5);
			}

		</style>
	</head>
	<body>  
		<div id="map">
			<img src="static/img/背景.jpg"/> 
			<div class="location" id="1" style="left: 998px;top: 578px;z-index: 1;">
				<img src="static/img/三角粿.png" onclick="clickImage(1)" class="transformClick"/>
				<img src="static/img/4.jpg" class="hoverImg" />
			</div>
			<div class="location" id="2" style="left: 973px;top: 625px;z-index: 1;">
				<img src="static/img/卤面.png" onclick="clickImage(2)" class="transformClick"/>
				<img src="static/img/1.jpg" class="hoverImg" />
			</div>
			<div class="location" id="3" style="left: 256px;top: 332px;z-index: 1;">
				<img src="static/img/豆花.png" onclick="clickImage(3)" class="transformClick"/>
				<img src="static/img/2.jpg" class="hoverImg" />
			</div>
			<div class="location" id="4" style="left: 478px;top: 375px;z-index: 1;">
				<img src="static/img/麻糍.png" onclick="clickImage(4)" class="transformClick"/>
				<img src="static/img/3.jpg" class="hoverImg" />
			</div>
			
			<div class="location" id="5" style="left: 236px;top: 376px;z-index: 1;">
				<img src="static/img/锅边糊.png" onclick="clickImage(5)" class="transformClick"/>
				<img src="static/img/8.jpg" class="hoverImg" />
			</div>
			<div class="location" id="6" style="left:247px;top: 543px;z-index: 1;">
				<img src="static/img/蚵仔煎.png" onclick="clickImage(6)" class="transformClick"/>
				<img src="static/img/6.jpg" class="hoverImg" />
			</div>
			<div class="location" id="7" style="left: 240px;top: 656px;z-index: 1;">
				<img src="static/img/四果汤.png" onclick="clickImage(7)" class="transformClick"/>
				<img src="static/img/5.jpg" class="hoverImg" />
			</div>
			<div class="location" id="8" style="left: 520px;top: 725px;z-index: 1;">
				<img src="static/img/豆干面.png" onclick="clickImage(8)" class="transformClick"/>
				<img src="static/img/7.jpg" class="hoverImg" />
			</div>
			<div class="location" id="9" style="left: 811px;top: 493px;z-index: 1;">
				<img src="static/img/公园东门.png" onclick="clickImage(9)" class="transformClick"/>
			</div>
			<div class="location" id="10" style="left: 220px;top: 840px;z-index: 1;">
				<img src="static/img/古城西门.png" onclick="clickImage(10)" class="transformClick"/>
			</div>
			<div class="location" id="11" style="left: 480px;top: 414px;z-index: 1;">
				<img src="static/img/孔庙果汁.png" onclick="clickImage(11)" class="transformClick"/>
				<img src="static/img/11.jpg" class="hoverImg" />
			</div>
			<div class="location" id="12" style="left: 485px;top: 545px;z-index: 1;">
				<img src="static/img/礼拜果汁.png" onclick="clickImage(12)" class="transformClick"/>
				<img src="static/img/12.jpg" class="hoverImg" />
			</div>
			<img id="paimeng" src="static/img/派蒙向导.png" alt="paimeng" style="position: absolute; width: 60px; height: 60px; display: none;z-index: 2;">
			<svg id="svgMap"
			 xmlns="http://www.w3.org/2000/svg"
			 xmlns:xlink="http://www.w3.org/1999/xlink"
			 width="977px" height="605px" >
			<path id="path" d="M976.500,432.995 L975.500,433.005 L973.516,244.529 L717.115,
			259.436 L706.761,431.1000 L975.000,431.1000 L975.000,432.1000 L706.701,432.1000 L696.409,
			604.525 L695.998,604.500 L695.998,604.500 L487.998,603.500 L487.998,603.484 L487.481,
			603.481 L487.500,603.981 L486.500,604.019 L486.480,603.477 L249.000,602.500 L32.002,
			603.500 L31.998,602.500 L248.998,601.500 L248.1000,602.000 L249.002,601.500 L250.497,
			601.506 L248.714,261.499 L247.971,261.496 L247.002,261.500 L247.002,261.492 L-0.002,
			260.500 L0.002,259.500 L247.971,260.496 L248.709,260.493 L247.500,30.003 L248.500,
			29.997 L249.709,260.488 L473.482,259.536 L463.500,1.019 L464.500,0.981 L474.482,
			259.532 L715.971,258.504 L715.971,258.501 L716.170,258.489 L722.501,152.970 L723.499,
			153.030 L717.175,258.431 L973.971,243.501 L974.019,244.334 L974.514,244.329 L976.500,
			432.995 ZM249.714,261.488 L251.497,601.510 L486.442,602.477 L473.500,261.019 L474.500,
			260.981 L487.443,602.481 L490.142,602.492 L490.142,602.510 L695.469,603.497 L705.699,
			432.1000 L705.000,432.1000 L705.000,431.1000 L705.759,431.1000 L716.109,259.504 L249.714,
			261.488 Z"/>
			</svg>
		</div>

		<p class="dist">距离:<span id="distance"></span>米</p>
		<p class="tim">时间:<span id="time"></span>分钟</p>
		<button class="buttonW" onclick="walk()"><b>步行</b></button>
		<button class="buttonB" onclick="bicycle()"><b>自行车</b></button>
		<button class="buttonC" onclick="car()" ><b>电动车</b></button>
		<button class="buttonR" onclick="reset()"><b>重新规划</b></button>
		
		<script>
			//定义起点和终点
			let startPoint=null;
			let endPoint=null;
			
			// 定义起点和终点的坐标，以像素为单位
			let startCoordinates = { x: 0, y: 0};
			let endCoordinates = { x: 0, y: 0};
			
			var paimeng = document.getElementById("paimeng");
			var path = document.getElementById('path');
			var svgMap = document.getElementById('svgMap');
			
			//定义起点数组
			var locations=[
				{id: 1, name: "三角粿", coordinates: {x: 1148, y: 538}},
				{id: 2, name: "卤面", coordinates: {x: 965, y: 625}},
				{id: 3, name: "豆花", coordinates: {x: 310, y: 300}},
				{id: 4, name: "麻糍", coordinates: {x: 478, y: 340}},
				{id: 5, name: "锅边糊", coordinates: {x: 406, y: 342}},
				{id: 7, name: "四果汤", coordinates: {x: 350, y: 620}},
				{id: 6, name: "蚵仔煎", coordinates: {x: 310, y: 390}},
				{id: 8, name: "豆干面", coordinates: {x: 620, y: 690}},
				{id: 9, name: "公园东门", coordinates: {x: 900, y: 443}},
				{id: 10, name: "古城西门", coordinates: {x: 260, y: 840}},
				{id: 11, name: "孔庙果汁", coordinates: {x: 480, y: 380}},
				{id: 12, name: "礼拜果汁", coordinates: {x: 480, y: 515}},
			];
			
			// SVG路径转换为坐标点数组并显示点
			var pathLength = path.getTotalLength();
			var points = [];
			for (var i = 0; i < pathLength; i += 1) {
			  var point = path.getPointAtLength(i);
			  points.push([point.x, point.y]);
			}
			
			// 创建一个节点类表示路径中的每个点
			class Node {
			  constructor(x, y, g, h, previous) {
			    this.x = x; // x坐标
			    this.y = y; // y坐标
			    this.g = g; // 起点到该点的移动成本
			    this.h = h; // 启发式函数的估计成本（这里使用曼哈顿距离）
			    this.f = g + h; 
			    this.previous = previous; // 之前的节点
			  }
			}
			
			// 计算曼哈顿距离
			function euclideanDistance(x1, y1, x2, y2) {
			  var dx = Math.abs(x2 - x1);
			  var dy = Math.abs(y2 - y1);
			  var distance=dx+dy; 
			  return distance;
			}
			
			// 使用A*算法找到最短路径
			function findShortestPath(startX, startY, endX, endY, points) {
				const openList = [];
				const closedList = [];
			
				// 添加起点到openList
				const startNode = new Node(startX, startY, 0, 0, null);
				openList.push(startNode);
				
				while (openList.length > 0) {
					// 在openList中寻找f值最小的节点
					let currentNode = openList[0];
					let currentIndex = 0;
					for (let i = 1; i < openList.length; i++) {
						if (openList[i].f < currentNode.f) {
							currentNode = openList[i];
							currentIndex = i;
						}
					}

					// 将当前节点移到closedList
					openList.splice(currentIndex, 1);
					closedList.push(currentNode);
			
					// 如果当前节点是终点，返回路径
					if (currentNode.x === endX && currentNode.y === endY) {
						const path = [];
						let node = currentNode;
						while (node != null) {
							path.push({ x: node.x, y: node.y });
							node = node.previous;
						}
						return path.reverse();
					}
			
					// 获取当前节点的邻居节点
					const neighbors = [];
						for (let i = 0; i < points.length; i++) {
						const point = points[i];
						// console.log("euclideanDistance:",euclideanDistance(currentNode.x, currentNode.y, point[0], point[1]));
						if (euclideanDistance(currentNode.x, currentNode.y, point[0], point[1]) <5) {
							neighbors.push(point);
						}
					}
			
					// 处理邻居节点
					for (let i = 0; i < neighbors.length; i++) {
						const neighbor = neighbors[i];
				
						// 如果邻居节点在closedList中，忽略
						if (closedList.some(node => node.x === neighbor[0] && node.y === neighbor[1])) {
							continue;
						}
				
						const g = currentNode.g + 1; // 移动成本为1
						const h = euclideanDistance(neighbor[0], neighbor[1], endX, endY);
						const f = g + h;
				
						// 如果邻居节点在openList中，更新g值和f值
						const existingNodeIndex = openList.findIndex(node => node.x === neighbor[0] && node.y === neighbor[1]);
						if (existingNodeIndex !== -1) {
							const existingNode = openList[existingNodeIndex];
							if (g < existingNode.g) {
							existingNode.g = g;
							existingNode.f = f;
							existingNode.previous = currentNode;
							}
						} else {
						// 否则，将邻居节点添加到openList
							const newNode = new Node(neighbor[0], neighbor[1], g, h, currentNode);
							openList.push(newNode);
						}
					}
				}
				// 如果openList为空，表示无法找到路径
				return null;
			}
			//计算总距离
			function allDistance(path) {
			  let totalDistance = 0;
			  for (let i = 0; i < path.length - 1; i++) {
			    const point1 = path[i];
			    const point2 = path[i + 1];
			    const distance = Math.abs(point2.x - point1.x) + Math.abs(point2.y - point1.y);
			    totalDistance += distance;
			  }
			  return totalDistance.toFixed(2);//取小数点后两位
			}
			
			// 在SVG上绘制路径
			function drawPath(inputPath) {
				for (var i=0; i < inputPath.length; i = i+3) {
					var circle = document.createElementNS("http://www.w3.org/2000/svg", "circle");
					circle.setAttribute("class", "circle");
					console.log("inputPath.length:",inputPath[i]);
					circle.setAttribute("cx", inputPath[i].x);
					circle.setAttribute("cy", inputPath[i].y);
					circle.setAttribute("r", 3.5);
					svgMap.appendChild(circle);
				}
			}
			
			// 函数：设置起点或终点
			let clickCount = 0; // 点击计数器
			let start, end; // 声明变量用于保存起点和终点的坐标
			let shortestPath=[];
			let Distance=0;
			let time=0;
			const distanceElement = document.getElementById('distance');
			const timeElement = document.getElementById('time');
			let isMoving = false;
			function clickImage(id) {
				var image = document.getElementById(id);
				if (clickCount >= 2) {
					alert("重新规划后可继续点击");
					return;
				}
				image.classList.toggle('clicked');
				clickCount++;
				if (clickCount === 1) {
					startPoint = locations.find(location => location.id === id);
					start = findNearestPointOnPath(startPoint.coordinates.x, startPoint.coordinates.y);
					console.log("start:",start);
					setPaimengPosition(start.x + 200, start.y + 220);
				} else if (clickCount === 2) {
					endPoint = locations.find(location => location.id === id);
					end = findNearestPointOnPath(endPoint.coordinates.x, endPoint.coordinates.y);
					console.log("end:",end);
					const svgPath = path.getAttribute('d');
					
					shortestPath = findShortestPath(start.x, start.y, end.x, end.y, points);
					
					drawPath(shortestPath);
					isMoving = true;
					moveImage(shortestPath);
					Distance=Math.round(allDistance(shortestPath)*0.41);
					distanceElement.innerHTML = Distance;
					time=((Distance/1.2)/60).toFixed(1);
					timeElement.innerHTML = time;
					const message=new SpeechSynthesisUtterance('总路程是' +Distance +'米' +',' +'步行用时' +time +'分钟');
					const speech=window.speechSynthesis;
					speech.speak(message);
					var imageButtons = document.getElementsByClassName('location');
					for (var i = 0; i < imageButtons.length; i++) {
						if (imageButtons[i].id !== id) {
							imageButtons[i].classList.remove('hoverImg')
							imageButtons[i].classList.remove('transformClick');
						}
					}
				}
			}
			

			//找到在svg'路径中与点击图片最近的点
			function findNearestPointOnPath(x, y) {
				var pathLength = path.getTotalLength();
				var minDistance = Number.MAX_VALUE;
				var nearestPoint;
				
				for (var i = 0; i < pathLength; i += 1) {
					var point = path.getPointAtLength(i);
					var distance = Math.sqrt(Math.pow(point.x - x+200, 2) + Math.pow(point.y - y+200, 2));
		
					if (distance < minDistance) {
						minDistance = distance;
						nearestPoint = point;
					}
				}
				return(nearestPoint);	
			}
			
			// 设置 paimeng 的位置
			function setPaimengPosition(x, y) {
				paimeng.style.left = x + 'px';
				paimeng.style.top = y + 'px';
				paimeng.style.display = 'block';
			}

			//图片移动
			async function moveImage(shortestPath) {
				for(var i = 0; i < shortestPath.length; i = i+3){
					setPaimengPosition(shortestPath[i].x + 200, shortestPath[i].y + 220);
					await new Promise(resolve => setTimeout(resolve, 100)); // 延时0.2秒
				}
				isMoving=false;
			}

			// 重置所有状态的函数
			function reset() {
				if (isMoving) {
					alert('等派蒙走完哦');
				    return; // 禁止执行下面的代码
				}
			    // 重置点击计数器
			    clickCount = 0;
			
			    // 重置起点和终点变量
			    start = null;
			    end = null;
			
			    // 移除所有路径上的圆圈元素
			    var circles = document.getElementsByClassName('circle');
			    while (circles.length > 0) {
			        circles[0].parentNode.removeChild(circles[0]);
			    }
			    // 隐藏 Paimeng 元素
			    paimeng.style.display = 'none';
				// 清空距离和时间信息
				document.getElementById('distance').innerText = '';
				document.getElementById('time').innerText = '';
				// 移除所有图片按钮上的点击样式和悬浮样式
				var imageButtons = document.getElementsByClassName('location');
				for (var i = 0; i < imageButtons.length; i++) {
					imageButtons[i].classList.remove('clicked');
					imageButtons[i].classList.add('transformClick');
				}
			}
			
			function walk() {
				time = ((Distance/1.2)/60).toFixed(1);
			    timeElement.innerHTML = time;
				const message=new SpeechSynthesisUtterance('步行用时' +time +'分钟');
				const speech=window.speechSynthesis;
				speech.speak(message);
				document.querySelector('.buttonW').classList.add('active');
				document.querySelector('.buttonB').classList.remove('active');
				document.querySelector('.buttonC').classList.remove('active');
			}
	
			function bicycle() {
				time = ((Distance/5.5)/60).toFixed(1);
				timeElement.innerHTML = time;
				const message=new SpeechSynthesisUtterance('骑自行车用时' +time +'分钟');
				const speech=window.speechSynthesis;
				speech.speak(message);
				document.querySelector('.buttonW').classList.remove('active');
				document.querySelector('.buttonB').classList.add('active');
				document.querySelector('.buttonC').classList.remove('active');
			}
	
			function car() {
				time = ((Distance/9.7)/60).toFixed(1);
				timeElement.innerHTML = time;
				const message=new SpeechSynthesisUtterance('骑电动车用时' +time +'分钟');
				const speech=window.speechSynthesis;
				speech.speak(message);
				document.querySelector('.buttonW').classList.remove('active');
				document.querySelector('.buttonB').classList.remove('active');
				document.querySelector('.buttonC').classList.add('active');
			}
		</script>
	</body>
</html>